<?php
namespace App\Modules\Popularize\Platform;

use Illuminate\Support\Facades\Redis;

class PlatformReportVivo {

    protected $platform;
    protected $device;
    protected $userId;


    const ACTIVITE_EVENT = 'ACTIVATION';//自定义激活
    const REGISTER_EVENT = 'REGISTER';//自定义注册
    const PAY_EVENT = 'PAY';//自定义付费
    const PAY_ONETIME_EVENT = 'PAY_ONETIME';//付费次数

    protected $callback='https://marketing-api.vivo.com.cn/openapi/v1/advertiser/behavior/upload?';//用户行为数据上传
    protected $srcType = 'APP';//数据源类型
    protected $pkgName = 'com.ningjing.dada';//应用包名todo
    protected $srcId = 'ds-202307045530';//数据源id
    protected $userIdType = 'OAID';//用户标识类型
    //商业开放平台=》应用管理=》我的应用
    protected $clientId = '20230818024';
    protected $clientSecret = 'D63EBD08F2FC910FAA6D733C783FF01AD09B00059A6136FC7E443081CED8063A';

    //vivo的access_token值缓存
    protected $accessTokenRedisKey = 'ADVERTISEMENT:VIVO:TOKEN';

    protected $redisPay = 'ADVERTISEMENT:VIVO:PAY:%s'; //汇报记录，防止多次汇报

    public function __construct($device, $userId)
    {
        $this->device = $device;
        $this->userId = $userId;
    }

    //激活
    public function actviteEvent($tomorrow=0)
    {
        $requestData = $this->_buildRequestData(self::ACTIVITE_EVENT);
        if (empty($requestData)) {
            return false;
        }
        return $this->_report(self::ACTIVITE_EVENT, $requestData);
    }

    //注册
    public function registerEvent()
    {
        $requestData = $this->_buildRequestData(self::REGISTER_EVENT);
        if (empty($requestData)) {
            return false;
        }
        return $this->_report(self::REGISTER_EVENT, $requestData);
    }

    //付费
    public function payEvent($amount=0)
    {
        $requestData = $this->_buildRequestData(self::PAY_EVENT, $amount);
        if (empty($requestData)) {
            return false;
        }
        return $this->_report(self::PAY_EVENT, $requestData);
    }

    //组成请求参数
    private function _buildRequestData($type, $payAmount = 0){
        //明细数据列表
        $dataList = [
            'userIdType' => $this->userIdType,
            'userId' => $this->device['oaid'],
            'cvType' => $type,
            'cvTime' => time() * 1000,
            'requestId' => $this->device['rid'],
            'creativeId' => $this->device['request_info']['creativeId'],
        ];
        if($type == self::PAY_EVENT) {
            $dataList['cvParam'] = $payAmount;
        }

        //请求参数
        $requestData = [
            'srcType' => $this->srcType,
            'pkgName' => $this->pkgName,
            'srcId' => $this->srcId,
            'dataList' => $dataList,
        ];

        return $requestData;
    }

    //上报vivo服务器
    private function _report($type, $requestData){
        if (empty($requestData)) {
            return false;
        }
        $accessToken = $this->_getToken();
        if (empty($accessToken)) {
            return false;
        }
        $callback = sprintf("%s&access_token=%s&timestamp=%s&nonce=%s&advertiser_id=",
            $this->callback, $accessToken, time()* 1000, $this->_createSign($requestData, time()));
        try{
            $header = ['Content-Type' => 'application/json'];
            $result = curl_request($callback, $requestData, 'json', 'POST', $header);
            write_log('Advertisement', 'platform_vivo_success', [$type, $callback, $requestData, $result]);
        }catch (\Exception $exception){
            write_log('Advertisement', 'platform_vivo_error', [$type, $callback, $requestData, $result]);
            return false;
        }
        $result = json_decode($result);

        return isset($result->code) &&  $result->code == 0;
    }

    //获取token
    private function _getToken(){
        $flag = 0;//0=正常 1=重新获取 2=刷新
        do {
            //refresh_token有效期
            $refreshTokenDate = Redis::hget($this->accessTokenRedisKey, "refresh_token_date");
            if (empty($refreshTokenDate)) {
                $flag = 1;
                break;
            }
            $refreshToken = Redis::hget($this->accessTokenRedisKey, "refresh_token");
            if (empty($refreshToken)) {
                $flag = 1;
                break;
            }
            //是否失效
            $refreshTokenDate = floor($refreshTokenDate / 1000);
            if ($refreshTokenDate < time()) {
                $flag = 1;
                break;
            }

            //access_token有效期
            $accessDate = Redis::hget($this->accessTokenRedisKey, "token_date");
            if (empty($accessDate)) {
                $flag = 2;
                break;
            }
            $accessToken = Redis::hget($this->accessTokenRedisKey, "access_token");
            if (empty($accessToken)) {
                $flag = 2;
                break;
            }
            //是否失效
            $accessDate = floor($accessDate / 1000);
            if ($accessDate < time()) {
                $flag = 2;
                break;
            }

        } while (false);

        //重新获取
        //如果拿不到就直接返回吧，别挣扎
        if($flag == 1) {
            write_log('Advertisement', 'platform_vivo', ['Get RefreshToken Failed']);
        }

        //刷新
        if($flag == 2) {
            $refreshUrl = 'https://marketing-api.vivo.com.cn/openapi/v1/oauth2/refreshToken';
            $params = [
                'client_id' => $this->clientId,
                'client_secret' => $this->clientSecret,
                'refresh_token' => $refreshToken,
            ];
            $result = curl_request($refreshUrl, $params, 'urlencoded', 'GET');
            $result = json_decode($result);
        }
        if(!empty($result)) {
            //如果拿不到就直接返回吧，别挣扎
            if (!isset($result->code) || $result->code != 0) {
                write_log('Advertisement', 'platform_vivo', ['Get Access Token Error', $result]);
                return null;
            }
            $accessToken = isset($result->data->access_token) ? $result->data->access_token : '';
            $refreshToken = isset($result->data->refresh_token) ? $result->data->refresh_token : '';
            $accessDate = isset($result->data->token_date) ? $result->data->token_date : '';
            $refreshDate = isset($result->data->refresh_token_date) ? $result->data->refresh_token_date : '';
            Redis::hset($this->accessTokenRedisKey, 'access_token', $accessToken);
            Redis::hset($this->accessTokenRedisKey, 'refresh_token', $refreshToken);
            Redis::hset($this->accessTokenRedisKey, 'token_date', $accessDate);
            Redis::hset($this->accessTokenRedisKey, 'refresh_token_date', $refreshDate);
            Redis::EXPIRE($this->accessTokenRedisKey, 365 * 86400);
        }

        //正常
        if($flag == 0) {
            Redis::EXPIRE($this->accessTokenRedisKey, 365 * 86400);
            return $accessToken;
        }

        return null;
    }

    private function _createSign($postData,$time,$salt = 'e0u6fnlag06lc3pl'){
        $data = json_encode($postData).$time.$salt;
        return md5($data);
    }
}
